package com.lzh.runke.core.service.impl;


import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.lzh.runke.core.entity.BaseEntity;
import com.lzh.runke.core.entity.spec.BaseSpec;
import com.lzh.runke.core.service.IBaseService;
import com.lzh.runke.core.web_base.Result;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.reflect.MethodUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.List;

/**
 * 实现BaseService抽象类
 */
public abstract class BaseServiceImpl<Mapper, Entity extends BaseEntity, Spec extends BaseSpec> implements IBaseService<Entity, Spec> {

    @Autowired
    protected Mapper mapper;

    /**
     * 保存（插入/更新）
     * 根据ID是否为空判断
     *
     * @param entity
     * @return
     */
    @Transactional
    @Override
    public Result<Integer> save(Entity entity) {
        if (StringUtils.isBlank(entity.getId())) {
            return this.insert(entity);
        } else {
            return this.update(entity);
        }
    }

    @Transactional
    @Override
    public Result<Integer> insert(Entity entity) {
        try {
            Object result = MethodUtils.invokeMethod(mapper, "insert", entity);
            int resultInt = Integer.parseInt(String.valueOf(result));
            if (resultInt > 0) {
                return Result.<Integer>builder().success(true).data(resultInt).build();
            }
        } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
            e.printStackTrace();
        }
        return Result.<Integer>builder().success(false).message("新增失败").build();
    }

    @Transactional
    @Override
    public Result<Integer> insertBatch(Collection<Entity> entity) {
        try {
            Object result = MethodUtils.invokeMethod(mapper, "insertBatch", entity);
            int resultInt = Integer.parseInt(String.valueOf(result));
            if (resultInt > 0) {
                return Result.<Integer>builder().success(true).data(resultInt).message("新增成功").build();
            }
        } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
            e.printStackTrace();
        }
        return Result.<Integer>builder().success(false).message("新增失败").build();
    }

    @Transactional
    @Override
    public Result<Integer> update(Entity entity) {
        try {
            Object result = MethodUtils.invokeMethod(mapper, "update", entity);
            int resultInt = Integer.parseInt(String.valueOf(result));
            if (resultInt > 0) {
                return Result.<Integer>builder().success(true).data(resultInt).message("修改成功").build();
            }
        } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
            e.printStackTrace();
        }
        return Result.<Integer>builder().success(false).message("修改失败").build();
    }

    @Transactional
    @Override
    public Result<Integer> updateBySpec(Entity entity, Spec spec) {
        try {
            Object result = MethodUtils.invokeMethod(mapper, "updateBySpec", new Object[]{entity, spec});
            int resultInt = Integer.parseInt(String.valueOf(result));
            if (resultInt > 0) {
                return Result.<Integer>builder().success(true).data(resultInt).message("根据条件更新记录成功").build();
            }
        } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
            e.printStackTrace();
        }
        return Result.<Integer>builder().success(false).message("根据条件更新记录失败").build();
    }

    @Transactional
    @Override
    public Result<Integer> delete(Entity entity) {
        try {
            Object result = MethodUtils.invokeMethod(mapper, "delete", entity);
            int resultInt = Integer.parseInt(String.valueOf(result));
            if (resultInt > 0) {
                return Result.<Integer>builder().success(true).data(resultInt).message("删除记录成功").build();
            }
        } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
            e.printStackTrace();
        }
        return Result.<Integer>builder().success(false).message("删除记录失败").build();
    }

    @Transactional
    @Override
    public Result<Integer> deleteBySpec(Spec spec) {
        try {
            Object result = MethodUtils.invokeMethod(mapper, "deleteBySpec", spec);
            int resultInt = Integer.parseInt(String.valueOf(result));
            if (resultInt > 0) {
                return Result.<Integer>builder().success(true).data(resultInt).message("条件删除记录成功").build();
            }
        } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
            e.printStackTrace();
        }
        return Result.<Integer>builder().success(false).message("条件删除记录失败").build();
    }

    @Override
    public Result<Entity> findById(String id) {
        Assert.hasText(id, "主键参数不能为空");
        try {
            Object result = MethodUtils.invokeMethod(mapper, "findById", id);
            return Result.<Entity>builder().success(true).data((Entity) result).build();
        } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
            e.printStackTrace();
        }
        return Result.<Entity>builder().success(false).message("查询记录失败").build();
    }

    @Override
    public Result<List<Entity>> findAll() {
        try {
            Object result = MethodUtils.invokeMethod(mapper, "findAll", null);
            return Result.<List<Entity>>builder().success(true).data((List<Entity>) result).build();
        } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
            e.printStackTrace();
        }
        return Result.<List<Entity>>builder().success(false).message("根据条件查询记录失败").build();
    }

    @Override
    public Result<List<Entity>> findBySpec(Spec spec) {
        try {
            Object result = MethodUtils.invokeMethod(mapper, "findBySpec", spec);
            return Result.<List<Entity>>builder().success(true).data((List<Entity>) result).build();
        } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
            e.printStackTrace();
        }
        return Result.<List<Entity>>builder().success(false).message("根据条件查询记录失败").build();
    }

    @Override
    public Result<List<Entity>> findBySpecForPage(Spec spec) {
        try {
            PageHelper.startPage(spec.getPageNo(), spec.getPageSize(), true);
            Object result = MethodUtils.invokeMethod(mapper, "findBySpecForPage", spec);

            Page<Entity> entityPage = (Page<Entity>) result;

            return Result.<List<Entity>>builder().success(true).data(entityPage.getResult()).total(entityPage.getTotal()).build();
        } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
            e.printStackTrace();
        }
        return Result.<List<Entity>>builder().success(false).message("根据条件分页查询记录失败").build();
    }

}